package cur.nature.starter.common.idgenerator.sequence;

import cur.nature.framework.core.sequence.SeqIdUtil;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import cur.nature.framework.core.log.LOG;
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

//@Configuration
public class SequenceIdConfig {

    @Autowired
    private SequenceDao sequenceDao;
    protected final ConcurrentMap<String, String> seqCache = new ConcurrentHashMap<>();

    @Value("${server.port}")
    private int port;

    @PostConstruct
    public void init() {
        final Long workerId = getWorkId();
        LOG.info("workerId:{}", workerId);

         // 使用sequence生成id
        new SeqIdUtil((tableName)->{
            // 创建 sequence
            String seqName = seqCache.get(tableName);
            try {
                if (seqName == null) {
                    seqName = tableName.toUpperCase() + "_SEQ";
                    if (!sequenceDao.existSel(seqName)) {
                        sequenceDao.creatSeq(seqName);
                    }
                    seqCache.put(tableName, seqName);
                }
            } catch (Exception e) {
                LOG.warn("create sequence err:{}",e.getMessage());
            }
            // 查询 next id
            return sequenceDao.querySeq(seqName);
        });
//        LOG.info("next id : {}", SeqIdUtil.generateId("admin_sys_user"));
    }

    @PreDestroy
    public void destroy() {
        LOG.info("id config destory :{}", 0);
    }

    // 取0-255位机器码, 通过 ip 加 端口 计算出来, 也可以通过数据库配置
    private Long getWorkId(){
        try {
            String hostAddress = Inet4Address.getLocalHost().getHostAddress() + port;
            int[] ints = StringUtils.toCodePoints(hostAddress);
            int sums = 0;
            for(int b : ints){
                sums += b;
            }
            return (long)(sums % 256);
        } catch (UnknownHostException e) {
            // 如果获取失败，则使用随机数备用
            return RandomUtils.nextLong(0,255);
        }
    }
}
